优化窗口 resize 事件
问题描述
使用 useResizeObserver 监视 document.body 时,当 body 被设置了固定 height 属性后,窗口高度变化无法被正确检测到,导致以下问题:
- 窗口高度只能减小,不能增大
- 仅在宽度变化时才触发回调
- 高度变化后逻辑不再执行
根因分析
问题链路
body.style.height = computedHeight
│
▼
body 尺寸不再随窗口高度变化
│
▼
ResizeObserver 无法检测到 body 尺寸变化
│
▼
回调函数不执行 → 布局不更新
text
ResizeObserver vs window.resize
| 特征 | ResizeObserver | window.resize |
|---|---|---|
| 监听对象 | DOM 元素尺寸 | 窗口尺寸 |
| 触发条件 | 元素尺寸变化 | 窗口尺寸变化 |
| 受 CSS 影响 | 是 | 否 |
| 适用场景 | 监听容器大小 | 监听窗口大小 |
解决方案
替换为 window.resize 事件
// 修改前:使用 ResizeObserver
import { useResizeObserver } from '@vueuse/core'
useResizeObserver(document.body, (entries) => {
const { width } = entries[0].contentRect
// 布局逻辑...
})
// 修改后:使用 window resize 事件
import { useEventListener } from '@vueuse/core'
useEventListener(window, 'resize', () => {
const width = window.innerWidth
const height = window.innerHeight
// 布局逻辑不变,后续代码无需修改
})
typescript
为什么 window.resize 更合适
window.innerWidth/innerHeight不受 CSS 影响- 无论 body 的
height如何设置,窗口尺寸变化都能被检测到 - 后续布局逻辑完全不用变动
完整修复代码
import { useEventListener } from '@vueuse/core'
// 监听窗口 resize 事件
useEventListener(window, 'resize', () => {
const width = window.innerWidth
// 后续逻辑保持不变
if (width < 768) {
// 移动端布局
isCollapsed.value = true
} else {
// 桌面端布局
isCollapsed.value = false
}
})
typescript
关键要点
- 当对 body 设置固定高度后,
ResizeObserver无法检测窗口高度变化 - 使用
window.resize事件直接读取window.innerWidth替代 useEventListener(VueUse) 提供自动清理,无需手动移除监听器- 修改后后续布局逻辑完全不变,仅替换监听方式
↑